package com.yoki.cloud.common.protocol.radius.attribute.attr.type;

import com.yoki.cloud.common.utils.bytes.ByteUtils;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

/**
 * @author Sky$
 * @Description: TODO
 * @date 2018/1/17$ 11:45$
 */
@Data
@NoArgsConstructor
@AllArgsConstructor
public class VendorType {

    public static int INDEX_VENDOR_ID = 0;
    public static int LENGTH_VENDOR_ID = 4;

    public static int INDEX_VENDOR_TYPE = LENGTH_VENDOR_ID;
    public static int LENGTH_VENDOR_TYPE = 1;

    public static int INDEX_VENDOR_LENGTH = INDEX_VENDOR_TYPE + LENGTH_VENDOR_TYPE;
    public static int LENGTH_VENDOR_LENGTH = 1;

    public static int INDEX_VENDOR_VALUE = INDEX_VENDOR_LENGTH + LENGTH_VENDOR_LENGTH;

    private int vendorId;
    private int type;
    private int length;
    private String value;

    public byte[] getBytes() {
        if (null == this.value) {
            throw new NullPointerException();
        }
        byte[] valueBytes = ByteUtils.getUtf8Byte(this.value);
        byte[] bytes = new byte[LENGTH_VENDOR_ID + LENGTH_VENDOR_TYPE + LENGTH_VENDOR_LENGTH + valueBytes.length];

        for (int i = INDEX_VENDOR_ID; i < INDEX_VENDOR_TYPE; i++) {
            bytes[i] = (byte) ((vendorId >> ((LENGTH_VENDOR_ID - 1 - i) * 8)) & 0xff);
        }

        for (int i = INDEX_VENDOR_TYPE; i < INDEX_VENDOR_LENGTH; i++) {
            bytes[i] = (byte) ((type >> ((LENGTH_VENDOR_TYPE - 1 - i) * 8)) & 0xff);
        }

        for (int i = INDEX_VENDOR_LENGTH; i < INDEX_VENDOR_VALUE; i++) {
            bytes[i] = (byte) ((length >> ((LENGTH_VENDOR_LENGTH - 1 - i) * 8)) & 0xff);
        }
        System.arraycopy(valueBytes, 0, bytes, INDEX_VENDOR_VALUE, valueBytes.length);
        return bytes;
    }

    public void parse(byte[] input) {
        Integer vendorId = 0;
        for (int i = INDEX_VENDOR_ID; i < INDEX_VENDOR_TYPE; i++) {
            vendorId = vendorId | ((input[i] & 0xff) << ((LENGTH_VENDOR_ID - 1 - i) * 8));
        }
        this.vendorId = vendorId;
        Integer type = 0;
        for (int i = INDEX_VENDOR_TYPE; i < INDEX_VENDOR_LENGTH; i++) {
            type = type | ((input[i] & 0xff) << ((LENGTH_VENDOR_TYPE - 1 - i) * 8));
        }
        this.type = type;
        Integer length = 0;
        for (int i = INDEX_VENDOR_LENGTH; i < INDEX_VENDOR_VALUE; i++) {
            length = length | ((input[i] & 0xff) << ((LENGTH_VENDOR_LENGTH - 1 - i) * 8));
        }
        this.length = length;
        byte[] valueBytes = new byte[input.length - (LENGTH_VENDOR_ID + LENGTH_VENDOR_TYPE + LENGTH_VENDOR_LENGTH)];
        System.arraycopy(input, INDEX_VENDOR_VALUE, valueBytes, 0, valueBytes.length);
        this.value = ByteUtils.getUtf8String(valueBytes);
    }

}